package mongodb

import (
	"SystemExploration/mongodb/db"
	"SystemExploration/task"
	"SystemExploration/task/itemdb"
	"context"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo/options"
	"time"
)

//用户表
type Users struct {
	Username string `bson:"username"`
	Password string `bson:"password"`
	Prx      string `bson:"prx"`
}

//任务表
type Taskcron struct {
	Name    string   `bson:"name"`    //任务名称
	Machine string   `bson:"machine"` //机器人
	Crons   string   `bson:"crons"`   //任务表达式 时间格式
	People  []string `bson:"people"`  //通知人列表
	State   int64    `bson:"state"`   //任务状态 0 录入 1 执行 2取消
	Type    int64    `bson:"type"`    //任务类型 1-ping 2 数据库 3 ...
	Url     string   `bson:"url"`     //链接地址
}

//记录表
type Tasklog struct {
	TaskName  string    `bson:"task_name" json:"task_name"` //任务ID
	AddTime   time.Time `bson:"add_time" json:"add_time"`   //执行时间
	Consuming int64     `bson:"consuming" json:"consuming"` //耗时
	Result    string    `bson:"result" json:"result"`       //任务结果
}

//查询当前可以执行的任务执行
func TaskAdd() {
	//查数据库 有没有需要执行的任务
	taskcronTable := db.Database.Collection("taskcron")
	filter := bson.D{{"state", 1}}
	cur, err := taskcronTable.Find(context.TODO(), filter)
	if err != nil {
		return
	}
	for cur.Next(context.TODO()) {
		// create a value into which the single document can be decoded
		var elem Taskcron
		err = cur.Decode(&elem)
		if err != nil {
			return
		}

		//操作定时任务
		taskContent := itemdb.ItemInfo{
			Name:    elem.Name,
			Machine: elem.Machine,
			Crons:   elem.Crons,
			Url:     elem.Url,
			People:  elem.People,
			State:   elem.State,
			Type:    1,
		}

		task.AddTask(taskContent)
	}
	if err = cur.Err(); err != nil {
		return
	}
	// Close the cursor once finished
	cur.Close(context.TODO())
}

//添加用户
func AddUser() {
	//添加用户表
	userinfo := new(Users)
	err := FindUserOne(bson.D{{"username", "JwAdmin"}}, userinfo)
	if err != nil {
		//插入数据
		userinfo.Username = "JwAdmin"
		userinfo.Password = "JwAdmin"
		userinfo.Prx = "Jw"
		_ = AddUserOne(userinfo)
	}
}

//用户操作 操作
//用户表 查一条数据
func FindUserOne(filter bson.D, user *Users) error {
	usersTable := db.Database.Collection("users")
	err := usersTable.FindOne(context.TODO(), filter).Decode(user)
	return err
}

//添加用户
func AddUserOne(user *Users) error {
	//插入单条
	usersTable := db.Database.Collection("users")
	_, err := usersTable.InsertOne(context.TODO(), user)
	return err
}

//任务操作//

// FindTaskOne 查询单个任务
func FindTaskOne(filter bson.D, taskcron *Taskcron) error {
	taskcronTable := db.Database.Collection("taskcron")
	err := taskcronTable.FindOne(context.TODO(), filter).Decode(taskcron)
	return err
}

// FindTaskAll 查询多个任务
func FindTaskAll(page, limit int64) (taskcron []*Taskcron, count int64, err error) {
	findOptions := options.Find()
	findOptions.SetLimit(limit)
	findOptions.SetSkip((page - 1) * limit)
	findOptions.SetSort(bson.D{{"_id", -1}})

	filter := bson.D{}

	taskcronTable := db.Database.Collection("taskcron")
	cur, err := taskcronTable.Find(context.TODO(), filter, findOptions)

	for cur.Next(context.TODO()) {
		// create a value into which the single document can be decoded
		var elem Taskcron
		err = cur.Decode(&elem)
		if err != nil {
			return
		}
		taskcron = append(taskcron, &elem)
	}
	if err = cur.Err(); err != nil {
		return
	}

	// Close the cursor once finished
	cur.Close(context.TODO())

	count, err = taskcronTable.CountDocuments(context.TODO(), filter)
	return
}

// FindTaskAdd 添加任务
func FindTaskAdd(taskcron *Taskcron) error {
	//插入单条
	taskcronTable := db.Database.Collection("taskcron")
	_, err := taskcronTable.InsertOne(context.TODO(), taskcron)
	return err
}

// FindTaskUp 更新任务
func FindTaskUp(filter bson.D, updata bson.M) error {
	//插入单条
	taskcronTable := db.Database.Collection("taskcron")
	_, err := taskcronTable.UpdateOne(context.TODO(), filter, updata)
	return err
}

//日志记录

// AddOne 添加日志
func AddLogOne(log *Tasklog) error {
	//插入单条
	logTable := db.Database.Collection("logs")
	_, err := logTable.InsertOne(context.TODO(), log)
	return err
}

func FindLogAll(page, limit int64, serech string) (taskcron []*Tasklog, count int64, err error) {
	findOptions := options.Find()
	findOptions.SetLimit(limit)
	findOptions.SetSkip((page - 1) * limit)
	findOptions.SetSort(bson.D{{"_id", -1}})
	filter := bson.D{{"task_name", serech}}
	if serech == "" {
		filter = bson.D{}
	}

	logsTable := db.Database.Collection("logs")
	cur, err := logsTable.Find(context.TODO(), filter, findOptions)

	for cur.Next(context.TODO()) {
		// create a value into which the single document can be decoded
		var elem Tasklog
		err = cur.Decode(&elem)
		if err != nil {
			return
		}
		taskcron = append(taskcron, &elem)
	}
	if err = cur.Err(); err != nil {
		return
	}

	// Close the cursor once finished
	cur.Close(context.TODO())

	count, err = logsTable.CountDocuments(context.TODO(), filter)
	return
}
